package com.shanzhu.beadhouse.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.shanzhu.beadhouse.common.config.wechat.WechatPayConfig;
import com.shanzhu.beadhouse.common.constant.CheckEnum;
import com.shanzhu.beadhouse.common.constant.ExceptionEnum;
import com.shanzhu.beadhouse.common.util.AssertUtil;
import com.shanzhu.beadhouse.dao.mapper.ElderMapper;
import com.shanzhu.beadhouse.dao.mapper.PaymentOrderMapper;
import com.shanzhu.beadhouse.entity.base.Result;
import com.shanzhu.beadhouse.entity.po.Elder;
import com.shanzhu.beadhouse.entity.po.PaymentOrder;
import com.shanzhu.beadhouse.entity.query.WechatPayQuery;
import com.shanzhu.beadhouse.entity.vo.WechatPayResultVo;
import com.shanzhu.beadhouse.service.WechatPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 微信支付服务实现类
 */
@Slf4j
@Service
public class WechatPayServiceImpl implements WechatPayService {

    @Resource
    private WechatPayConfig wechatPayConfig;
    
    @Resource
    private PaymentOrderMapper paymentOrderMapper;
    
    @Resource
    private ElderMapper elderMapper;

    @Override
    @Transactional
    public Result createPayment(WechatPayQuery query) {
        try {
            // 1. 验证老人信息
            Elder elder = elderMapper.selectById(query.getElderId());
            AssertUtil.notNull(elder, ExceptionEnum.NOT_ENTER);
            
            // 检查老人状态
            boolean checkFlag = Objects.equals(elder.getCheckFlag(), CheckEnum.ENTER.getStatus()) ||
                    Objects.equals(elder.getCheckFlag(), CheckEnum.EXIT_AUDIT.getStatus());
            AssertUtil.isTrue(checkFlag, ExceptionEnum.NOT_ENTER);
            
            // 2. 创建支付订单
            PaymentOrder paymentOrder = new PaymentOrder();
            paymentOrder.setOrderNo(generateOrderNo());
            paymentOrder.setElderId(query.getElderId());
            paymentOrder.setAmount(query.getAmount());
            paymentOrder.setPayType("WECHAT");
            paymentOrder.setStatus("PENDING");
            paymentOrder.setCreateTime(new Date());
            paymentOrder.setUpdateTime(new Date());
            paymentOrder.setRemark(query.getDescription());
            
            paymentOrderMapper.insert(paymentOrder);
            
            // 3. 调用微信支付API（这里简化处理，实际需要调用微信SDK）
            WechatPayResultVo resultVo = new WechatPayResultVo();
            resultVo.setOrderNo(paymentOrder.getOrderNo());
            resultVo.setStatus("PENDING");
            resultVo.setAmount(query.getAmount().toString());
            
            // 生成支付二维码URL（实际项目中需要调用微信API）
            String qrCodeUrl = generateQrCodeUrl(paymentOrder);
            resultVo.setQrCodeUrl(qrCodeUrl);
            
            log.info("创建微信支付订单成功: orderNo={}, elderId={}, amount={}", 
                    paymentOrder.getOrderNo(), query.getElderId(), query.getAmount());
            
            return Result.success(resultVo);
            
        } catch (Exception e) {
            log.error("创建微信支付订单失败: elderId={}, amount={}", query.getElderId(), query.getAmount(), e);
            return Result.error(ExceptionEnum.NOT_ENTER);
        }
    }

    @Override
    public Result queryPaymentStatus(String orderNo) {
        try {
            PaymentOrder paymentOrder = paymentOrderMapper.selectByOrderNo(orderNo);
            if (paymentOrder == null) {
                return Result.error( ExceptionEnum.NOT_EXIST);
            }
            
            WechatPayResultVo resultVo = new WechatPayResultVo();
            resultVo.setOrderNo(paymentOrder.getOrderNo());
            resultVo.setTransactionId(paymentOrder.getTransactionId());
            resultVo.setStatus(paymentOrder.getStatus());
            resultVo.setAmount(paymentOrder.getAmount().toString());
            
            if (paymentOrder.getPayTime() != null) {
                resultVo.setPayTime(paymentOrder.getPayTime().toString());
            }
            
            return Result.success(resultVo);
            
        } catch (Exception e) {
            log.error("查询支付状态失败: orderNo={}", orderNo, e);
            return Result.error(ExceptionEnum.NOT_EXIST);
        }
    }

    @Override
    @Transactional
    public String handlePaymentNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 读取微信回调数据
            String xmlData = readRequestBody(request);
            log.info("收到微信支付回调: {}", xmlData);
            
            // 解析XML数据（实际项目中需要验证签名）
            Map<String, String> notifyData = parseXmlData(xmlData);
            
            String orderNo = notifyData.get("out_trade_no");
            String transactionId = notifyData.get("transaction_id");
            String resultCode = notifyData.get("result_code");
            
            // 查询订单
            PaymentOrder paymentOrder = paymentOrderMapper.selectByOrderNo(orderNo);
            if (paymentOrder == null) {
                log.error("支付回调订单不存在: orderNo={}", orderNo);
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[订单不存在]]></return_msg></xml>";
            }
            
            // 检查是否已处理
            if ("SUCCESS".equals(paymentOrder.getStatus())) {
                log.info("订单已处理，跳过: orderNo={}", orderNo);
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            }
            
            if ("SUCCESS".equals(resultCode)) {
                // 支付成功，更新订单状态
                paymentOrder.setStatus("SUCCESS");
                paymentOrder.setTransactionId(transactionId);
                paymentOrder.setPayTime(new Date());
                paymentOrder.setUpdateTime(new Date());
                
                paymentOrderMapper.updateById(paymentOrder);
                
                // 给老人账户充值
                Elder elder = elderMapper.selectById(paymentOrder.getElderId());
                elder.setBalance(elder.getBalance().add(paymentOrder.getAmount()));
                elderMapper.updateById(elder);
                
                log.info("支付成功处理完成: orderNo={}, elderId={}, amount={}", 
                        orderNo, paymentOrder.getElderId(), paymentOrder.getAmount());
                
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } else {
                // 支付失败
                paymentOrder.setStatus("FAILED");
                paymentOrder.setUpdateTime(new Date());
                paymentOrderMapper.updateById(paymentOrder);
                
                log.info("支付失败: orderNo={}, resultCode={}", orderNo, resultCode);
                
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            }
            
        } catch (Exception e) {
            log.error("处理微信支付回调失败", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>";
        }
    }

    @Override
    public Result closePayment(String orderNo) {
        try {
            PaymentOrder paymentOrder = paymentOrderMapper.selectByOrderNo(orderNo);
            if (paymentOrder == null) {
                return Result.error( ExceptionEnum.NOT_EXIST);
            }
            
            if (!"PENDING".equals(paymentOrder.getStatus())) {
                return Result.error( ExceptionEnum.NOT_EXIST);
            }
            
            paymentOrder.setStatus("CANCELLED");
            paymentOrder.setUpdateTime(new Date());
            paymentOrderMapper.updateById(paymentOrder);
            
            log.info("关闭支付订单成功: orderNo={}", orderNo);
            return Result.success();
            
        } catch (Exception e) {
            log.error("关闭支付订单失败: orderNo={}", orderNo, e);
            return Result.error(ExceptionEnum.NOT_EXIST);
        }
    }

    @Override
    public Result refund(String orderNo, String reason) {
        try {
            PaymentOrder paymentOrder = paymentOrderMapper.selectByOrderNo(orderNo);
            if (paymentOrder == null) {
                return Result.error( ExceptionEnum.NOT_EXIST);
            }
            
            if (!"SUCCESS".equals(paymentOrder.getStatus())) {
                return Result.error( ExceptionEnum.NOT_EXIST);
            }
            
            // 这里需要调用微信退款API（简化处理）
            log.info("申请退款: orderNo={}, reason={}", orderNo, reason);
            
            return Result.success("退款申请已提交");
            
        } catch (Exception e) {
            log.error("申请退款失败: orderNo={}", orderNo, e);
            return Result.error(ExceptionEnum.NOT_EXIST);
        }
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        return "PAY" + System.currentTimeMillis() + IdUtil.getSnowflakeNextId();
    }

    /**
     * 生成支付二维码URL（简化实现）
     */
    private String generateQrCodeUrl(PaymentOrder paymentOrder) {
        // 实际项目中需要调用微信支付API生成二维码
        return "weixin://wxpay/bizpayurl?pr=" + paymentOrder.getOrderNo();
    }

    /**
     * 读取请求体
     */
    private String readRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = request.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }

    /**
     * 解析XML数据（简化实现）
     */
    private Map<String, String> parseXmlData(String xmlData) {
        Map<String, String> map = new HashMap<>();
        map.put("out_trade_no", "PAY" + System.currentTimeMillis());
        map.put("transaction_id", "wx" + System.currentTimeMillis());
        map.put("result_code", "SUCCESS");
        return map;
    }
} 